package bjtu.pinet.common.pinetpacket;

import bjtu.pinet.common.PinetEtherType;
import bjtu.pinet.utils.IPUtils;
import com.google.common.base.MoreObjects;
import org.onlab.packet.*;

import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

/**
 * author:chushuai
 * date:2021.2.13
 */
public class IPv4Packet extends BasePacket implements Serializable {
    private static final long serialVersionID = -453880105234314228L;
    protected byte version = 4;
    protected byte headerLength;
    protected byte diffServ;
    protected short totalLength;
    protected short identification;
    protected byte flags;
    protected short fragmentOffset;
    protected byte ttl;
    protected byte protocol;
    protected short checksum;
    protected String sourceAddress;
    protected String destinationAddress;
    protected byte[] options;
    protected boolean isTruncated = false;
    public IPv4Packet( IPv4 ipv4) {
        this.version = ipv4.getVersion();
        this.headerLength = ipv4.getHeaderLength();
        this.diffServ = ipv4.getDiffServ();
        this.totalLength = ipv4.getTotalLength();
        this.identification = ipv4.getIdentification();
        this.flags = ipv4.getFlags();
        this.fragmentOffset = ipv4.getFragmentOffset();
        this.ttl = ipv4.getTtl();
        this.protocol = ipv4.getProtocol();
        this.checksum = ipv4.getChecksum();
        this.sourceAddress = IPUtils.longToIP(IPUtils.toLong(ipv4.getSourceAddress()));
        this.destinationAddress = IPUtils.longToIP(IPUtils.toLong(ipv4.getDestinationAddress()));
        this.options = ipv4.getOptions();
        this.isTruncated = ipv4.isTruncated();
    }

    public byte getVersion() {
        return version;
    }

    public void setVersion(byte version) {
        this.version = version;
    }

    public byte getHeaderLength() {
        return headerLength;
    }

    public void setHeaderLength(byte headerLength) {
        this.headerLength = headerLength;
    }

    public byte getDiffServ() {
        return diffServ;
    }

    public void setDiffServ(byte diffServ) {
        this.diffServ = diffServ;
    }

    public short getTotalLength() {
        return totalLength;
    }

    public void setTotalLength(short totalLength) {
        this.totalLength = totalLength;
    }

    public short getIdentification() {
        return identification;
    }

    public void setIdentification(short identification) {
        this.identification = identification;
    }

    public byte getFlags() {
        return flags;
    }

    public void setFlags(byte flags) {
        this.flags = flags;
    }

    public short getFragmentOffset() {
        return fragmentOffset;
    }

    public void setFragmentOffset(short fragmentOffset) {
        this.fragmentOffset = fragmentOffset;
    }

    public byte getTtl() {
        return ttl;
    }

    public void setTtl(byte ttl) {
        this.ttl = ttl;
    }

    public byte getProtocol() {
        return protocol;
    }

    public void setProtocol(byte protocol) {
        this.protocol = protocol;
    }

    public short getChecksum() {
        return checksum;
    }

    public void setChecksum(short checksum) {
        this.checksum = checksum;
    }

    public String getSourceAddress() {
        return sourceAddress;
    }

    public void setSourceAddress(String sourceAddress) {
        this.sourceAddress = sourceAddress;
    }

    public String getDestinationAddress() {
        return destinationAddress;
    }

    public void setDestinationAddress(String destinationAddress) {
        this.destinationAddress = destinationAddress;
    }

    public byte[] getOptions() {
        return options;
    }

    public void setOptions(byte[] options) {
        this.options = options;
    }

    public boolean isTruncated() {
        return isTruncated;
    }

    public void setTruncated(boolean truncated) {
        isTruncated = truncated;
    }

    public String toString() {
        return MoreObjects.toStringHelper(this.getClass()).add("version", Byte.toString(this.version)).add("headerLength", Byte.toString(this.headerLength)).add("diffServ", Byte.toString(this.diffServ)).add("totalLength", Short.toString(this.totalLength)).add("identification", Short.toString(this.identification)).add("flags", Byte.toString(this.flags)).add("fragmentOffset", Short.toString(this.fragmentOffset)).add("ttl", Byte.toString(this.ttl)).add("protocol", Byte.toString(this.protocol)).add("checksum", Short.toString(this.checksum)).add("sourceAddress", this.sourceAddress).add("destinationAddress", this.destinationAddress).add("options", Arrays.toString(this.options)).add("isTruncated", Boolean.toString(this.isTruncated)).toString();
    }

    @Override
    public byte[] serialize() {
        return new byte[0];
    }
}